package com.wcfsy.wechat.wx.shiro;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.wcfsy.wechat.wx.um.entity.User;
import com.wcfsy.wechat.wx.um.service.IUserConService;

@Component("systemUserRealm")
public class SystemUserRealm extends AuthorizingRealm {
	private Logger logger = LoggerFactory.getLogger(SystemUserRealm.class);

	@Resource
	private IUserConService userConService;

	@PostConstruct
	public void initCredentialsMatcher() {
		// 该句作用是重写shiro的密码验证，让shiro用我自己的验证
		setCredentialsMatcher(new CustomCredentialsMatcher());
	}

	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(
			PrincipalCollection principals) {
		// 获取当前登录的用户名,等价于//String username = (String)
		// getAvailablePrincipal(principals);
		String currentUsername = (String) principals.getPrimaryPrincipal();

		User user = userConService.getByUserName(currentUsername);

		// List<String> roleList = new ArrayList<String>();
		// List<String> permissionList = new ArrayList<String>();
		// //从数据库中获取当前登录用户的详细信息
		// User user = userService.getByUsername(currentUsername);
		// if(null != user){
		// //实体类User中包含有用户角色的实体类信息
		// if(null!=user.getRoles() && user.getRoles().size()>0){
		// //获取当前登录用户的角色
		// for(Role role : user.getRoles()){
		// roleList.add(role.getName());
		// //实体类Role中包含有角色权限的实体类信息
		// if(null!=role.getPermissions() && role.getPermissions().size()>0){
		// //获取权限
		// for(Permission pmss : role.getPermissions()){
		// if(!StringUtils.isEmpty(pmss.getPermission())){
		// permissionList.add(pmss.getPermission());
		// }
		// }
		// }
		// }
		// }
		// }else{
		// throw new AuthorizationException();
		// }
		// //为当前用户设置角色和权限
		// SimpleAuthorizationInfo simpleAuthorInfo = new
		// SimpleAuthorizationInfo();
		// simpleAuthorInfo.addRoles(roleList);
		// simpleAuthorInfo.addStringPermissions(permissionList);
		SimpleAuthorizationInfo simpleAuthorInfo = new SimpleAuthorizationInfo();
		simpleAuthorInfo.addRole("admin");
		// 添加权限
		simpleAuthorInfo.addStringPermission("admin:manage");
		return simpleAuthorInfo;
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(
			AuthenticationToken authcToken) throws AuthenticationException {
		UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
		String username = token.getUsername();
		User user = userConService.getByUserName(username);
		if (user == null) {
			throw new UnknownAccountException("没有找到该账号");
		}
		SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(
				user.getUserName(), user.getPassword(), getName());
		this.setSession("currentUser", user);
		return info;
	}

	/**
	 * 将一些数据放到ShiroSession中,以便于其它地方使用
	 * 
	 * @see 比如Controller,使用时直接用HttpSession.getAttribute(key)就可以取到
	 */
	private void setSession(Object key, Object value) {
		Subject currentUser = SecurityUtils.getSubject();
		if (null != currentUser) {
			Session session = currentUser.getSession();
			logger.info("Session默认超时时间为{}秒", session.getTimeout() / 1000);
			if (null != session) {
				session.setAttribute(key, value);
			}
		}
	}

	@Override
	public String getName() {
		return getClass().getName();
	}
}
